package com.yinhe.util.jibeiSync;



import com.yinhe.model.GD_KBXNY;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @ClassName FileReadUtil
 * @Description QS、res文件解析
 * @Author xiaolongZzz66
 * @Time 2023/11/30 14:31
 * @Version 1.0
 */

@Slf4j
public class FileReadUtil {

    // 风能预测10h文件前缀
    public static final String WINDFORECASTPREFIX = "jibei_windSuper10h_";
    // 光伏预测10h文件前缀-集中式
    public static final String SOLARFORECASTPREFIX = "jibei_solarSuper10h_";
    // 光伏预测4h文件前缀-分布式
    public static final String SOLARFORECASTPREFIX_FBS = "jibei_Fbs_solarDiaoduSuper_";



    // 风能预测10day文件前缀
    public static final String WINDFORECASTPREFIX10DAY = "jibei_windDiaoduTenDay_";

    // 光伏预测10day文件前缀
    // public static final String SOLARFORECASTPREFIX10DAY = "jibei_solarDiaoduTenDaySum_";
    // public static final String SOLARFORECASTPREFIX10DAY = "jibei_solarDiaoduTenDay_";







    /**
         * 安分-解析文件
         * @return
         */
        public static <T> List<T> parseFile(File file,String table,Class<T> type) {
            // String encoding = "UTF-8";
            String encoding = "GBK";

            log.info("进入安分文件解析，解析文件表名{}",table);
            // 入库数据list
            List<T> tableData  = new ArrayList();
            try {
                // File file = new File(path);
                byte[] bytes = Files.readAllBytes(file.toPath());

                BufferedReader reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(bytes), encoding));
                // 当前表名
                String tabelName = null;
                // 当前表头
                List<String> tabelHeader = null;

                String line;
                while ((line = reader.readLine()) != null) {

                    // 如果为空、//，跳出本次循环（无用行）
                    if("".equals(line)  || line.startsWith("//") || line.startsWith("<!")){
                        continue;
                    }

                    //1、获取表开头标识和表名
                    if (line.startsWith("<") && !line.startsWith("<!")){
                        if(line.contains("::")){
                            tabelName = line.split("::")[0].substring(1);
                        }else {
                            tabelName = line.split(" ")[0].substring(1 );
                        }
                        continue;
                    }

                    // 2、读取表头
                    if (tabelName!=null && line.startsWith("@")){
                        String[] trimString = trimString(line);
                        tabelHeader = Arrays.asList(trimString);
                        continue;
                    }

                    //3、获取表结束标识,终止循环
                    String endFlag = "</" + tabelName;
                    if (line.startsWith(endFlag)){
                        // tabelName = null;
                        // tabelHeader = null;
                        // continue;
                        break;
                    }

                    //4、判断是否为当前表，如果是则读取中间表数据，并根据表名映射实体类
                    if (tabelName!=null && table.equals(tabelName) &&line.startsWith("#")){
                        // System.out.println(file+"文件"+table+"表，内容是："+line);
                        // log.info("当前文件{}，{}表内容是：{}",file,table,line);

                        // 获取表记录数据
                        String[] strings = trimString(line);
                        List<String> itemList = Arrays.asList(strings);

                        // 动态创建实体类
                        // 1、根据反射创建实体
                        // Class<?> beanClass = Class.forName("com.yinhe.model.jibeiPO." + tabelName + "_PO");
                        // Object javaBean = beanClass.newInstance();
                        // 2、根据泛型创建

                        T javaBean = type.getDeclaredConstructor().newInstance();

                        // 根据表头，动态赋值
                        for (int i = 0; i < tabelHeader.size(); i++) {
                            String fiel = tabelHeader.get(i);
                            // 特殊处理，正常名称只有：数字字母下划线，如果字段名不规范，包含其他字符，一概跳过不处理
                            boolean matches = fiel.matches("^[a-zA-Z0-9_]*$");
                            if(!matches) continue;

                            Field declaredField = javaBean.getClass().getDeclaredField(fiel);
                            // Field declaredField = beanClass.getDeclaredField(fiel);
                            if (declaredField!=null){
                                declaredField.setAccessible(true);
                                declaredField.set(javaBean,"''".equals(itemList.get(i))?"":itemList.get(i));
                            }
                        }
                        tableData.add(javaBean);
                    }

                }

                reader.close();
            } catch (Exception e) {
                log.info("文件解析异常，原因是：" + e);
            }

            // 返回数据，有hvbi就行同步
            return tableData;
        }


    /**
     * 安分-文件夹解析
     * @param fileName 文件名（对应的表所在的哪个文件名）
     * @param tableName 表名（对应文件中的表名）
     * @param nowNmaeTime 本次读取磁盘下的文件夹名
     * @param type po类
     * @param filePath 解析文件存放的磁盘路径
     * @return
     * @param <T>
     */
        public static <T> List<T> parseDir(String fileName, String tableName,String nowNmaeTime,Class<T> type,String filePath){
            log.info("安分数据解析----进入【文件夹】解析：当前解析文件名{}，表名{}，当前时刻值{}",fileName,tableName,nowNmaeTime);
            // 从redis中获取上次文件夹时间（文件夹名称）。//2023_11_29T15_00_00
            // LocalDateTime lastSyncTime =  DateTimeUtil.StringToLocateDate("2023-11-29 15:00:00");
            // String lastSyncTimeStr = formatISO8601(lastSyncTime);

            // 计算本次需要同步的文件夹名称(15min after)
            // String nowNmaeTime = DateTimeUtil.getIso8601NameByLocateDate(lastSyncTime);

            List<T> result = null;

            // 读取数据存放的文件夹，获取文件列表，遍历获取文件

            File file = new File(filePath);
            File[] listFiles = file.listFiles();
            if(listFiles!=null){
                for (File fileItem : listFiles) {
                    // 如果是文件夹才会解析，如果是压缩文件其他文件不处理，并且和redis中存放的数据一样
                    String dirName = fileItem.getName();
                    // nowNmaeTime获取处理最后两秒位值，因为这个秒钟可能不是固定的，但是其他值都是固定的
                    String nowName = nowNmaeTime.substring(0, 16);
                    if(fileItem.isDirectory()&&dirName.startsWith(nowName)){
                        File[] files = fileItem.listFiles();
                        for (File file1 : files) {
                            // 获取当前需要同步的文件夹下的对应的文件，并且取解析对应的table
                            if(file1.getName().equals(fileName)){
                               result =  parseFile(file1, tableName, type);
                            }
                        }
                    }
                }
            }
            log.info("本次文件解析完成----");
            return result;
        }


        // 解析行记录（去除特殊符号等无用字符）
        public static String[] trimString(String string){
            if (string.isEmpty()){
                return null;
            }
            // 去除数据行、数据头的@、#符号，将所有连续多个空格替换为一个空格
            String copeString = string.replace("@","").replace("#", "").trim().replaceAll("\\s+", " ");

            // 以空格分割
            String[] s = copeString.split(" ");
            return s;
        };


    /**
     * @descript 风力和光能预测数据--未来10小时（每15min一个的预测文件解析）--（规则是估计文件名中时间为起始时间，然后每15min中加一次）
     * @param dirPath 文件夹路径
     * @param filePrefix 文件名前缀
     * @return Map<String, LocalDateTime> String是符合条件最新的文件的全路径，LocalDateTime符合条件文件的最新时间
     */
    public static Map<String, LocalDateTime> parseWindAndSolarFile(String dirPath,String filePrefix){
            // 1、拿到今天所有文件名，并且根据文件名时间找出最新的文件，并记录时间。
            // 2、根据记录的时间去生成文件名，然后读取该文件数据，解析映射到实体类。
            // 3、在映射过程中，根据记录的时间，以及数据的顺序（首行1的数据是记录时间后15min），添加时刻值（以便后期数据更新）。
            // 4、hvbi同步数据，会根据时刻值为主键，如果之前存在就更新，不存在就新增。
        File dir = new File(dirPath);
        File[] files = dir.listFiles();
        log.info("进入风能光能未来小时h【文件夹】解析");

        // 最新时间(需要是今天的数据)
        LocalDateTime lastTime = DateTimeUtil.getToday0H0M0S().plusMinutes(-1);
        String lastName = null;

        for (int i = 0; i < files.length; i++) {
            File file = files[i];
            // 只解析文件，这里文件夹跳过
            if (file.isDirectory()) continue;

            String fileName = file.getName();
            // 如果不是以当前前缀的文件跳过
            if (!fileName.startsWith(filePrefix)) continue;


            String[] fileNameArr = fileName.split(filePrefix);
            // 后缀
            String fileNameStr = fileNameArr[fileNameArr.length - 1];
            String suffixTime = fileNameStr.substring(0, fileNameStr.length() - 3);
            // 拿到后缀时间
            LocalDateTime fileTime = DateTimeUtil.windSolarStringToLocalDT(suffixTime);

            if (fileTime.isAfter(lastTime)){
                lastTime = fileTime;
                lastName = fileName;
            }
        }

        Map<String, LocalDateTime> fileMap = new HashMap<>();
        if (lastName!=null){
            String windFilePath = dirPath + lastName;
            File windFile = new File(windFilePath);
            if (windFile.exists()){
                fileMap.put(windFilePath,lastTime);
            }
            log.info("获取待解析文件名称，文件：{}。",windFilePath);
        }

        return fileMap;
    }

    public static <T> List<T> parseWindAndSolarFileConten(File file,LocalDateTime startTimePoint,Class<T> type){
        String encoding = "GBK";

        log.info("进入风能和光能【文件】解析，文件名为：{}，起始时间是：{}",file.getName(),startTimePoint);
        // 入库数据list
        List<T> tableData  = new ArrayList();
        try {
            byte[] bytes = Files.readAllBytes(file.toPath());

            BufferedReader reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(bytes), encoding));

            // 当前表头
            List<String> tabelHeader = null;

            // 行数据字符串
            String line;
            // 当前是第几行
            int lineNum = 1;

            while ((line = reader.readLine()) != null) {
                // 如果为空、//，跳出本次循环（无用行）
                if("".equals(line)  || line.startsWith("//") || line.startsWith("<!") || line.startsWith("<")){
                    continue;
                }

                if (line.startsWith("</")){//结束标签，终止循环
                    break;
                }

                // 2、读取表头 ,@ 表头行
                if (line.startsWith("@")){
                    String[] trimString = trimString(line);
                    //特殊处理
                    tabelHeader = toEnglinshWord(Arrays.asList(trimString));
                    continue;
                }

                //4、# 是数据行，读取有效数据
                if (tabelHeader!=null && line.startsWith("#")){
                    // 获取表记录数据
                    String[] strings = trimString(line);
                    List<String> itemList = Arrays.asList(strings);

                    // 动态创建实体类
                    T javaBean = type.getDeclaredConstructor().newInstance();

                    // 根据表头，动态赋值
                    for (int i = 0; i < tabelHeader.size(); i++) {
                        String fiel = tabelHeader.get(i);
                        Field declaredField = javaBean.getClass().getDeclaredField(fiel);
                        if (declaredField!=null){
                            declaredField.setAccessible(true);
                            declaredField.set(javaBean,("''".equals(itemList.get(i)) || "null".equals(itemList.get(i).toLowerCase()) )?"":itemList.get(i));
                        }
                    }

                    // 设置时间点值
                    Field timePoint = javaBean.getClass().getDeclaredField("timePoint");
                    if (timePoint!=null){
                        timePoint.setAccessible(true);
                        // DateTimeUtil
                        LocalDateTime dateTime = startTimePoint.plusMinutes(15 * lineNum);//每行数据是行号的15min的时间值
                        // 转换格式字符串
                        String format = dateTime.format(DateTimeFormatter.ofPattern(DateTimeUtil.StandTime));
                        timePoint.set(javaBean,format);
                    }
                    lineNum++;//增加行号
                    tableData.add(javaBean);
                    log.info("当前行文件解析后数据为："+javaBean.toString());
                }
            }

            reader.close();
        } catch (Exception e) {
            log.info("文件解析异常，原因是：" + e);
        }

        return tableData;
    }

    private static List<String> toEnglinshWord(List<String> asList) {
        List<String> strings = new ArrayList<>();
        // 顺序，从小到大，分别对应PO的filed
        if ( asList==null || asList.size()==0) return null;
        String[] windsolar = {"id","name","value"};
        for (int i = 0; i < asList.size(); i++) {
            strings.add(i, windsolar[i]);
        }
        return strings;
    }

    /**
     * @descript 风力和光能预测数据--未来10天（每天一个的预测文件解析）--（规则是根据表行头中日期为起始日期，然后每15min中加一次）
     * @param dirPath 文件夹路径
     * @param spliceChart 分割符
     * @return
     */
    public static Map<String,LocalDateTime> parseWindAndSolar10dayFile(String dirPath,String spliceChart){
        // 1、拿到今天所有文件名，并且根据文件名时间找出最新的文件，并记录时间。
        // 2、根据记录的时间去生成文件名，然后读取该文件数据，解析映射到实体类。
        // 3、在映射过程中，根据记录的时间，以及数据的顺序（首行1的数据是记录时间后15min），添加时刻值（以便后期数据更新）。
        // 4、hvbi同步数据，会根据时刻值为主键，如果之前存在就更新，不存在就新增。
        log.info("进入风能光能未来10天day预测数据【文件夹】解析");
        File dir = new File(dirPath);
        File[] files = dir.listFiles();
        // 最新时间(必须今天后的)
        LocalDateTime lastTime = DateTimeUtil.getToday0H0M0S().plusMinutes(-1);

        String lastName = null;

        for (int i = 0; i < files.length; i++) {
            File file = files[i];
            // 不处理文件夹
            if (file.isDirectory()) continue;

            String fileName = file.getName();
            // 不是以我们前缀开头一律不要
            if (!fileName.startsWith(spliceChart)) continue;


            String[] fileNameArr = fileName.split(spliceChart);
            // 后缀
            String fileNameStr = fileNameArr[fileNameArr.length - 1];
            String suffixTime = fileNameStr.substring(0, fileNameStr.length() - 3);

            LocalDateTime fileTime = DateTimeUtil.windSolarStringTo10dayLocalDT(suffixTime.split("-")[0]);

            if ( fileTime.isAfter(lastTime)){
                lastTime = fileTime;
                lastName = fileName;
            }
        }

        Map<String, LocalDateTime> fileMap = new HashMap<>();
        if (lastName!=null){
            String windFilePath = dirPath + lastName;
            File windFile = new File(windFilePath);
            if (windFile.exists()){
                fileMap.put(windFilePath,lastTime);
            }
            log.info("获取待解析文件名称，文件：{}。",windFilePath);
        }

        return fileMap;
    }


    /**
     * 解析10天预测文件内容
     * @param file 文件对象
     * @param startPoint 文件名字中开始时间
     * @param type po字节类
     * @return
     * @param <T>
     */
    public static <T> List<T> parseWindAndSolar10dayFileConten(File file,LocalDateTime startPoint,Class<T> type){
        String encoding = "GBK";

        log.info("进入风能和光能【文件】解析，文件名为：{}",file.getName());
        // 入库数据list
        List<T> tableData  = new ArrayList();
        try {
            byte[] bytes = Files.readAllBytes(file.toPath());

            BufferedReader reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(bytes), encoding));

            // 当前表头
            List<String> tabelHeader = null;

            // 行数据字符串
            String line;
            // 当前是第几行
            int lineNum = 1;
            // 当前预测开始时间
            LocalDateTime startForecastDate = null;
            // 当前日期
            LocalDate startForecastD = null;

            while ((line = reader.readLine()) != null) {
                // 如果为空、//，跳出本次循环（无用行）
                if("".equals(line)  || line.startsWith("//") || line.startsWith("<!") ){
                    continue;
                }

                if (line.startsWith("</")){//结束标签，终止循环
                    continue;
                }

                if(line.startsWith("<")){
                    String[] strings = line.replace(">", "").split("date=");
                    String timeStr = strings[1].replace("\'", "");
                    LocalDate parseDate = LocalDate.parse(timeStr, DateTimeFormatter.ofPattern(DateTimeUtil.STANDDATE));

                    startForecastDate = parseDate.atTime(LocalTime.of(00, 00, 00));

                    startForecastD = parseDate;
                    lineNum = 1;

                    continue;
                }

                // 2、读取表头 ,@ 表头行
                if (line.startsWith("@")){
                    String[] trimString = trimString(line);
                    //特殊处理
                    tabelHeader = toEnglinshWord(Arrays.asList(trimString));
                    continue;
                }

                //4、# 是数据行，读取有效数据
                if (tabelHeader!=null && line.startsWith("#")){
                    // 获取表记录数据
                    String[] strings = trimString(line);
                    List<String> itemList = Arrays.asList(strings);

                    // 动态创建实体类
                    // 2、根据泛型创建
                    T javaBean = type.getDeclaredConstructor().newInstance();

                    // 根据表头，动态赋值
                    for (int i = 0; i < tabelHeader.size(); i++) {
                        String fiel = tabelHeader.get(i);
                        Field declaredField = javaBean.getClass().getDeclaredField(fiel);
                        if (declaredField!=null){
                            declaredField.setAccessible(true);
                            declaredField.set(javaBean,("''".equals(itemList.get(i)) || "null".equals(itemList.get(i).toLowerCase()) )?"":itemList.get(i));
                        }
                    }

                    // 设置时间点值
                    Field timePoint = javaBean.getClass().getDeclaredField("timePoint");
                    if (timePoint!=null){
                        timePoint.setAccessible(true);
                        // DateTimeUtil
                        LocalDateTime dateTime = startForecastDate.plusMinutes(15 * lineNum);//每行数据是行号的15min的时间值
                        // 转换格式字符串
                        String format = dateTime.format(DateTimeFormatter.ofPattern(DateTimeUtil.StandTime));
                        // 这里每日的24h会判定为第二天的0点
                        // if(dateTime.toLocalDate().isAfter(startForecastD)){
                        //     format = startForecastD.format(DateTimeFormatter.ofPattern(DateTimeUtil.STANDDATE)) + " " + "24:00:00";
                        // }
                        timePoint.set(javaBean,format);
                    }
                    lineNum++;//增加行号
                    tableData.add(javaBean);
                }
            }

            reader.close();
        } catch (Exception e) {
            log.info("文件解析异常，原因是：" + e);
        }

        return tableData;
    }

    /**
     *
     * @param dirPath 文夹路径
     * @param spliceChart 文件前缀
     * @param methods 方法名字-这个方法是用来处理gdkbxnyPrefix文件前缀处理后的时间日期的（根据方法名字，通过反射去调用方法）
     * @return
     */
    public static Map<String, LocalDateTime> parseGDKBXNYFileName(String dirPath, String spliceChart,String methods) throws ClassNotFoundException, InvocationTargetException, IllegalAccessException, NoSuchMethodException {

        log.info("进入数据【文件夹】解析");
        File dir = new File(dirPath);
        File[] files = dir.listFiles();
        // 最新时间(必须今天后的)
        LocalDateTime lastTime = DateTimeUtil.getToday0H0M0S().plusMinutes(-1);

        String lastName = null;

        for (int i = 0; i < files.length; i++) {
            File file = files[i];
            // 不处理文件夹
            if (file.isDirectory()) continue;

            String fileName = file.getName();
            // 不是以我们前缀开头一律不要
            if (!fileName.startsWith(spliceChart)) continue;


            String[] fileNameArr = fileName.split(spliceChart);
            String fileNameStr = fileNameArr[fileNameArr.length - 1];

            // 后缀时间
            // T javaBean = type.getDeclaredConstructor().newInstance();

            // methods根据名称去调用时间处理方法（参数：前缀切割后的字符串，返回值：一个LocalDateTime字符串）FileReadUtil.class
            Class<?> fileReadUtil = Class.forName("com.yinhe.util.jibeiSync.FileReadUtil");
            Method declaredMethod = fileReadUtil.getMethod(methods,String.class);
            // Object fileIns = fileReadUtil.getDeclaredConstructor().newInstance();
            LocalDateTime fileTime = (LocalDateTime)declaredMethod.invoke(declaredMethod, fileNameStr);

            // String suffixTime = fileNameStr.substring(0, fileNameStr.length() - 3);
            // LocalDateTime fileTime = DateTimeUtil.windSolarStringTo10dayLocalDT(suffixTime.split("-")[0]);



            if ( fileTime.isAfter(lastTime)){
                lastTime = fileTime;
                lastName = fileName;
            }
        }

        Map<String, LocalDateTime> fileMap = new HashMap<>();
        if (lastName!=null){
            String windFilePath = dirPath + lastName;
            File windFile = new File(windFilePath);
            if (windFile.exists()){
                fileMap.put(windFilePath,lastTime);
            }
            log.info("获取待解析文件名称，文件：{}。",windFilePath);
        }
        return fileMap;
    }

    /**
     * 冀北全网断面受阻预测gd_qwdmsz
     * @param file 解析文件对象
     * @param startForecastDate 解析文件名时间
     * @param type 类对象
     * @return
     * @param <T>
     */
    public static <T> List<T> parseGDXNYFileConten(File file, LocalDateTime startForecastDate, Class<T> type) {
        String encoding = "GBK";

        log.info("进入【文件】解析，文件名为：{}",file.getName());
        // 入库数据list
        List<T> tableData  = new ArrayList();
        try {
            byte[] bytes = Files.readAllBytes(file.toPath());

            BufferedReader reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(bytes), encoding));

            List<String> tabelHeader = Arrays.asList(new String[]{"name", "tag", "timeHHmm", "value"});
            // 行数据字符串
            String line;
            // 当前是第几行
            int lineNum = 1;
            // 当前日期
            LocalDate startForecastD = null;

            while ((line = reader.readLine()) != null) {
                if (!line.startsWith("gd_qwdmsz") ) continue;
                if(line.startsWith("gd_qwdmsz") && line.contains("dliang")) break;
                //4、读取有效数据
                if (line.startsWith("gd_qwdmsz")){
                    // 获取表记录数据
                    String[] strings = trimStringTwo(line,",");
                    List<String> itemList = Arrays.asList(strings);

                    // 动态创建实体类
                    // 2、根据泛型创建
                    T javaBean = type.getDeclaredConstructor().newInstance();

                    // 根据表头，动态赋值
                    for (int i = 0; i < tabelHeader.size(); i++) {
                        String fiel = tabelHeader.get(i);
                        Field declaredField = javaBean.getClass().getDeclaredField(fiel);
                        if (declaredField!=null){
                            declaredField.setAccessible(true);
                            declaredField.set(javaBean,("''".equals(itemList.get(i)) || "null".equals(itemList.get(i).toLowerCase()) )?"":itemList.get(i));
                        }
                    }

                    // 设置时间点值
                    Field timePoint = javaBean.getClass().getDeclaredField("timePoint");
                    if (timePoint!=null){
                        timePoint.setAccessible(true);
                        // DateTimeUtil
                        LocalDateTime dateTime = startForecastDate.plusMinutes(15 * lineNum);//每行数据是行号的15min的时间值
                        // 转换格式字符串
                        String format = dateTime.format(DateTimeFormatter.ofPattern(DateTimeUtil.StandTime));
                        // 这里每日的24h会判定为第二天的0点
                        // if(dateTime.toLocalDate().isAfter(startForecastD)){
                        //     format = startForecastD.format(DateTimeFormatter.ofPattern(DateTimeUtil.STANDDATE)) + " " + "24:00:00";
                        // }
                        timePoint.set(javaBean,format);
                    }
                    lineNum++;//增加行号
                    tableData.add(javaBean);
                }
            }

            reader.close();
        } catch (Exception e) {
            log.info("文件解析异常，原因是：" + e);
        }

        return tableData;
    }


    public static LocalDateTime getGDKBXNYFileNameTime(String fileNameStr){
        String suffixTime = fileNameStr.substring(0, fileNameStr.length() - 4);
        LocalDateTime fileTime = DateTimeUtil.windSolarStringTo10dayLocalDT(suffixTime);
        return fileTime;
    }

    // 解析行记录（去除特殊符号等无用字符）
    public static String[] trimStringTwo(String string,String spliteChart){
        if (string.isEmpty()){
            return null;
        }
        // 去除数据行、数据头的@、#符号，将所有连续多个空格替换为一个空格
        String copeString = string.replace("@","").replace("#", "").trim().replaceAll("\\s+", " ");

        // 以空格分割
        String[] s = copeString.split(spliteChart);
        return s;
    };

}
